package cn.wizzer.app.web.commons.ext.websocket.action.attendant;

import cn.wizzer.app.sys.modules.services.SysDictService;
import cn.wizzer.app.user.modules.models.User;
import cn.wizzer.app.user.modules.models.vo.ChatUserVO;
import cn.wizzer.app.user.modules.services.UserService;
import cn.wizzer.app.web.commons.ext.websocket.filter.TokenFilter;
import cn.wizzer.app.web.commons.ext.websocket.main.action.BaseNettyAction;
import cn.wizzer.app.web.commons.ext.websocket.main.action.NettyAction;
import cn.wizzer.app.web.commons.ext.websocket.main.base.NettyCache;
import cn.wizzer.app.web.commons.ext.websocket.main.result.ChatResult;
import cn.wizzer.app.web.commons.utils.NettyMsgUtil;
import cn.wizzer.framework.util.Result;
import cn.wizzer.framework.base.model.enums.BizExceptionEnum;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSONObject;
import io.netty.channel.Channel;
import org.nutz.dao.Cnd;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;

import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

@IocBean
@NettyAction(uri = "/attendant/open", filters = {TokenFilter.class})
public class OpenAction extends BaseNettyAction {

    @Inject
    @Reference
    private UserService userService;
    @Inject
    @Reference
    private SysDictService dictService;
    @Inject
    private NettyMsgUtil nettyMsgUtil;

    /**
     * 是否已选择客服/是否有未读消息
     *
     * @param income
     * @param params
     * @return
     */
    @Override
    public Result action(Channel income, JSONObject params) {
        ChatUserVO targetAttendant = NettyCache.globalGet(NettyCache.localGet(income, "targetAttendant"));
        ChatUserVO self = NettyCache.globalGet(params.get("appid"));
        if (self.isAttendant()) {
            Result.breakWith(BizExceptionEnum.ATTENDANT_PLEASE_LOGIN_PC);
        }
        if (targetAttendant == null) {
            //分配客服
            targetAttendant = distribute();
            if (targetAttendant == null) {
                // todo 没有客服要发送这个吗
//                nettyMsgUtil.send(income, ChatResult.MessageTypeEnum.ACTION, ChatResult.ActionEnum.ERROR, self, "hi");
            } else {
                NettyCache.localSet(income, "targetAttendant", targetAttendant.getId());
                targetAttendant.getUsers().add(self.getId());
                //通知客服
                Channel channel = targetAttendant.getChannel();
                nettyMsgUtil.send(channel, ChatResult.MessageTypeEnum.ACTION, ChatResult.ActionEnum.JOIN, self, null);

                //发送欢迎语到用户端
                nettyMsgUtil.send(income, ChatResult.MessageTypeEnum.ACTION, ChatResult.ActionEnum.SEND, targetAttendant, "hi");
            }
        }
        return Result.success(targetAttendant);
    }

    private ChatUserVO distribute() {
        List<User> query = userService.query(Cnd.where("isOnline", "=", 1).and("attendant", "=", 1));
        //在线客服聊天人数最少的其中一位
        Optional<ChatUserVO> min = query.stream()
                .map(user -> NettyCache.<ChatUserVO>globalGet(user.getId()))
                .filter(Objects::nonNull)
                .min(Comparator.comparing(ChatUserVO::getChatUserSize));
        if (!min.isPresent()) {
            return null;
        }
        return min.get();
    }

}
